#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<assert.h>
#include<unistd.h>
#include<string.h>
#include<stdio.h>

#define TASKNUMS 10

typedef void(* func_t)();
// creat tasks
void sync_disk()
{
    printf("updating data\n");
}
void sync_log()
{
    printf("sync log\n");
}
void sync_send()
{
    printf("sync net send\n");
}



int LoadTask(func_t func);

func_t funcTask[TASKNUMS] = {NULL};

void InitTask()
{
    int i = 0;
    for(; i < TASKNUMS; i++)
        funcTask[i] = NULL;
    LoadTask(sync_log);
    LoadTask(sync_disk);
    LoadTask(sync_send);
}

int  LoadTask(func_t func)
{
    int i = 0;
    for(;i < TASKNUMS; i++)
    {
        if (funcTask[i] == NULL)
            break;
    }
    if(i == TASKNUMS)
        return -1;
    else
        funcTask[i] = func;
    return 0;
}
void RunTask()
{
    int i = 0;
    for(; funcTask[i]; i++)
    {
        if(funcTask[i] == NULL)
            continue;
        funcTask[i]();
    }  
}

int  Add_to_Top(int top)
{
      int sum = 0;
      int i = 0;
      for(;i < top;i++ )
      {
          sum += i;
      }
      return sum;
}
int main()
{
    //查看退出码,一般不会超过255个
   // int i = 0;
   // for(;i < 255; i++)
   // {
   //     printf("%d: %s\n",i,strerror(i));
   // }
    //什么是进程退出？1.父进程回收子进程，2.查看子进程事情办得怎么样
      pid_t id =  fork();
      assert(id >=0 );
      (void)id;
      if(id == 0)
      {
        int cnt = 5;
          //子进程
         int ret =  Add_to_Top(100);
         while(cnt)
         {
            printf("我是子进程，我还活着还有%dS\n",cnt);
            cnt--;
            sleep(1);
         }
         if(ret == 5500)
            return 0;
        else
            return 1;

      }
      //父进程
      int status = 0;
     // waitpid(id,&status,0); //阻塞等待
     // printf("我是父进程：pid:%d exit_code:%d exit_signal:%d\n",getpid(),WEXITSTATUS(status),status & 0x7F);
      
      InitTask();    
      while(1)
      {
          //采用非阻塞轮询的方法进行等待
          int retid = waitpid(id,&status,WNOHANG);
          if(retid < 0)
          {
              printf("waitpid error\n");
              exit(1);
          }
          else if(retid ==  0) //child is lived
          {
              RunTask();
              sleep(1);
              continue;
          }
          else
          {
              if(WIFEXITED(status))
              {
                        
                   printf("等待成功，我是父进程：pid:%d exit_code:%d exit_signal:%d\n",getpid(),WEXITSTATUS(status),status & 0x7F);
              }
              else
              {
                  
                  printf("等待成功，我是父进程：pid:%d exit_code:%d exit_signal:%d\n",getpid(),WEXITSTATUS(status),status & 0x7F);
              }
             break; 
          }
      }
    return 0;
}
